package org.base23.video.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.base23.video.domain.dto.*;
import org.base23.video.service.AiGuidanceService;
import org.base23.video.service.VideoAnalysisApiService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * AI指导服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AiGuidanceServiceImpl implements AiGuidanceService {
    
    private final ChatClient.Builder chatClientBuilder;
    private final VectorStore vectorStore;
    private final VideoAnalysisApiService videoAnalysisApiService;
    
    // 内存中存储会话（实际项目中应该使用数据库）
    private final Map<String, AiGuidanceConversation> conversations = new ConcurrentHashMap<>();
    
    private ChatClient chatClient;
    
    @Override
    public AiGuidanceConversation createConversation(String resultId, String sportType, String userId) {
        log.info("创建AI指导会话，结果ID: {}, 运动类型: {}, 用户ID: {}", resultId, sportType, userId);
        
        String conversationId = UUID.randomUUID().toString();
        
        AiGuidanceConversation conversation = new AiGuidanceConversation();
        conversation.setConversationId(conversationId);
        conversation.setResultId(resultId);
        conversation.setSportType(sportType);
        conversation.setUserId(userId);
        conversation.setStatus(AiGuidanceConversation.ConversationStatus.ACTIVE);
        conversation.setCreateTime(LocalDateTime.now());
        conversation.setLastUpdateTime(LocalDateTime.now());
        
        // 获取分析结果概要
        try {
            VideoAnalysisResult.VideoAnalysisData analysisData = videoAnalysisApiService.getAnalysisResult(resultId);
            String summary = generateAnalysisSummary(analysisData, sportType);
            conversation.setAnalysisSummary(summary);
            
            // 生成初始推荐问题
            List<String> suggestedQuestions = generateInitialSuggestedQuestions(analysisData, sportType);
            conversation.setSuggestedQuestions(suggestedQuestions);
            
        } catch (Exception e) {
            log.warn("获取分析结果失败，使用默认推荐问题: {}", e.getMessage());
            conversation.setSuggestedQuestions(getDefaultSuggestedQuestions(sportType));
        }
        
        // 添加欢迎消息
        AiGuidanceMessage welcomeMessage = AiGuidanceMessage.createAiMessage(
            generateWelcomeMessage(sportType), 
            AiGuidanceMessage.MessageType.INSTRUCTION
        );
        conversation.getMessages().add(welcomeMessage);
        
        conversations.put(conversationId, conversation);
        
        log.info("AI指导会话创建成功，会话ID: {}", conversationId);
        return conversation;
    }
    
    @Override
    public AiGuidanceResponse askQuestion(AiGuidanceRequest request) {
        log.info("处理AI指导问题，会话ID: {}, 问题: {}", request.getConversationId(), request.getQuestion());
        
        // 获取或创建会话
        AiGuidanceConversation conversation = getOrCreateConversation(request);
        
        // 添加用户消息到会话历史
        AiGuidanceMessage userMessage = AiGuidanceMessage.createUserMessage(request.getQuestion());
        if (request.getRelatedTimestamp() != null) {
            userMessage.setRelatedTimestamp(request.getRelatedTimestamp());
        }
        conversation.getMessages().add(userMessage);
        
        // 使用AI生成回复
        AiGuidanceResponse response = generateAiResponse(conversation, request);
        
        // 添加AI回复到会话历史
        AiGuidanceMessage aiMessage = AiGuidanceMessage.createAiMessage(
            response.getAiResponse(), 
            AiGuidanceMessage.MessageType.ANSWER
        );
        conversation.getMessages().add(aiMessage);
        
        // 更新会话
        conversation.setLastUpdateTime(LocalDateTime.now());
        conversations.put(conversation.getConversationId(), conversation);
        
        return response;
    }
    
    @Override
    public AiGuidanceConversation getConversation(String conversationId) {
        return conversations.get(conversationId);
    }
    
    @Override
    public List<AiGuidanceConversation> getUserConversations(String resultId) {
        return conversations.values().stream()
                .filter(conv -> resultId.equals(conv.getResultId()))
                .sorted((a, b) -> b.getCreateTime().compareTo(a.getCreateTime()))
                .toList();
    }
    
    @Override
    public List<String> generateSuggestedQuestions(String resultId, String sportType) {
        try {
            VideoAnalysisResult.VideoAnalysisData analysisData = videoAnalysisApiService.getAnalysisResult(resultId);
            return generateInitialSuggestedQuestions(analysisData, sportType);
        } catch (Exception e) {
            log.warn("生成推荐问题失败，使用默认问题: {}", e.getMessage());
            return getDefaultSuggestedQuestions(sportType);
        }
    }
    
    @Override
    public void endConversation(String conversationId) {
        AiGuidanceConversation conversation = conversations.get(conversationId);
        if (conversation != null) {
            conversation.setStatus(AiGuidanceConversation.ConversationStatus.COMPLETED);
            conversation.setLastUpdateTime(LocalDateTime.now());
        }
    }
    
    @Override
    public void cleanupExpiredConversations() {
        LocalDateTime expireTime = LocalDateTime.now().minusDays(7); // 7天过期
        
        conversations.entrySet().removeIf(entry -> {
            try {
                LocalDateTime lastUpdateTime = entry.getValue().getLastUpdateTimeAsLocalDateTime();
                return lastUpdateTime == null || lastUpdateTime.isBefore(expireTime);
            } catch (Exception e) {
                // 如果解析失败，则认为是过期的
                return true;
            }
        });
    }
    
    /**
     * 获取或创建会话
     */
    private AiGuidanceConversation getOrCreateConversation(AiGuidanceRequest request) {
        if (request.getConversationId() != null) {
            AiGuidanceConversation existing = conversations.get(request.getConversationId());
            if (existing != null) {
                return existing;
            }
        }
        
        // 创建新会话
        return createConversation(request.getResultId(), request.getSportType(), request.getUserId());
    }
    
    /**
     * 生成AI回复
     */
    private AiGuidanceResponse generateAiResponse(AiGuidanceConversation conversation, AiGuidanceRequest request) {
        if (chatClient == null) {
            chatClient = chatClientBuilder.build();
        }
        
        // 构建上下文提示
        String contextPrompt = buildContextPrompt(conversation, request);
        
        try {
            String aiReply = chatClient.prompt()
                    .user(contextPrompt)
                    .call()
                    .content();
            
            AiGuidanceResponse response = new AiGuidanceResponse();
            response.setConversationId(conversation.getConversationId());
            response.setAiResponse(aiReply);
            response.setResponseType(AiGuidanceResponse.ResponseType.DIRECT_ANSWER);
            response.setConfidence(85); // 默认置信度
            
            // 生成后续推荐问题
            List<String> suggestions = generateFollowUpQuestions(request.getQuestion(), conversation.getSportType());
            response.setSuggestedQuestions(suggestions);
            
            return response;
            
        } catch (Exception e) {
            log.error("AI回复生成失败: {}", e.getMessage(), e);
            return createFallbackResponse(conversation.getConversationId(), request.getQuestion());
        }
    }
    
    /**
     * 构建上下文提示
     */
    private String buildContextPrompt(AiGuidanceConversation conversation, AiGuidanceRequest request) {
        StringBuilder prompt = new StringBuilder();
        
        prompt.append("你是一个专业的运动分析AI教练，专门帮助用户理解和改进他们的运动技术。\n\n");
        prompt.append("运动类型: ").append(conversation.getSportType()).append("\n");
        prompt.append("分析结果概要: ").append(conversation.getAnalysisSummary()).append("\n\n");
        
        // 添加对话历史
        prompt.append("对话历史:\n");
        List<AiGuidanceMessage> recentMessages = conversation.getMessages()
                .stream()
                .skip(Math.max(0, conversation.getMessages().size() - 6)) // 最近6条消息
                .toList();
        
        for (AiGuidanceMessage msg : recentMessages) {
            if (msg.getSenderType() == AiGuidanceMessage.SenderType.USER) {
                prompt.append("用户: ").append(msg.getContent()).append("\n");
            } else if (msg.getSenderType() == AiGuidanceMessage.SenderType.AI_ASSISTANT) {
                prompt.append("AI教练: ").append(msg.getContent()).append("\n");
            }
        }
        
        prompt.append("\n当前问题: ").append(request.getQuestion()).append("\n\n");
        
        if (request.getRelatedTimestamp() != null) {
            prompt.append("用户关注的时间点: ").append(request.getRelatedTimestamp()).append("秒\n\n");
        }
        
        prompt.append("请提供专业、友好、具体的指导建议。如果涉及特定技术动作，请给出详细的改进步骤。");
        
        return prompt.toString();
    }
    
    /**
     * 生成分析结果概要
     */
    private String generateAnalysisSummary(VideoAnalysisResult.VideoAnalysisData analysisData, String sportType) {
        if (analysisData == null || analysisData.getFrames() == null || analysisData.getFrames().isEmpty()) {
            return "分析数据不完整";
        }
        
        StringBuilder summary = new StringBuilder();
        summary.append("运动类型: ").append(sportType).append("\n");
        summary.append("视频信息: ").append(analysisData.getVideoInfo().getFps()).append("fps, ");
        summary.append(analysisData.getVideoInfo().getTotalFrames()).append("总帧数\n");
        summary.append("分析帧数: ").append(analysisData.getFrames().size()).append("\n");
        
        // 分析关节角度统计
        if (!analysisData.getFrames().isEmpty() && !analysisData.getFrames().get(0).getPersons().isEmpty()) {
            summary.append("检测到的主要运动特征: 关节角度变化、姿态分析等");
        }
        
        return summary.toString();
    }
    
    /**
     * 生成初始推荐问题
     */
    private List<String> generateInitialSuggestedQuestions(VideoAnalysisResult.VideoAnalysisData analysisData, String sportType) {
        List<String> questions = new ArrayList<>();
        
        switch (sportType.toLowerCase()) {
            case "running":
                questions.add("我的跑步姿势有什么问题吗？");
                questions.add("如何改善我的步频和步幅？");
                questions.add("我的着地方式是否正确？");
                questions.add("摆臂动作需要调整吗？");
                break;
            case "basketball_shooting":
                questions.add("我的投篮姿势标准吗？");
                questions.add("出手角度和力度如何调整？");
                questions.add("如何提高投篮的稳定性？");
                questions.add("我的站位和平衡有问题吗？");
                break;
            default:
                questions.add("我的整体技术动作如何？");
                questions.add("有哪些地方需要重点改进？");
                questions.add("如何避免运动损伤？");
                questions.add("推荐一些针对性的训练方法？");
        }
        
        return questions;
    }
    
    /**
     * 获取默认推荐问题
     */
    private List<String> getDefaultSuggestedQuestions(String sportType) {
        return Arrays.asList(
            "我的技术动作有什么问题？",
            "如何改进我的表现？",
            "有什么训练建议吗？",
            "如何避免运动损伤？"
        );
    }
    
    /**
     * 生成欢迎消息
     */
    private String generateWelcomeMessage(String sportType) {
        return String.format("👋 欢迎来到AI运动指导！我是你的专业%s教练。我已经分析了你的运动视频，随时准备回答你的问题。你可以询问技术动作、改进建议或任何相关问题。", 
            getSportDisplayName(sportType));
    }
    
    /**
     * 生成后续推荐问题
     */
    private List<String> generateFollowUpQuestions(String currentQuestion, String sportType) {
        List<String> suggestions = new ArrayList<>();
        
        if (currentQuestion.toLowerCase().contains("问题") || currentQuestion.toLowerCase().contains("错误")) {
            suggestions.add("如何具体改正这个问题？");
            suggestions.add("这个问题会导致什么后果？");
            suggestions.add("有什么练习方法吗？");
        } else if (currentQuestion.toLowerCase().contains("改进") || currentQuestion.toLowerCase().contains("提高")) {
            suggestions.add("改进后效果如何评估？");
            suggestions.add("需要多长时间能看到改善？");
            suggestions.add("有什么注意事项吗？");
        } else {
            suggestions.add("还有其他需要注意的地方吗？");
            suggestions.add("如何进行针对性训练？");
            suggestions.add("这个技术动作的关键点是什么？");
        }
        
        return suggestions;
    }
    
    /**
     * 创建fallback响应
     */
    private AiGuidanceResponse createFallbackResponse(String conversationId, String question) {
        AiGuidanceResponse response = new AiGuidanceResponse();
        response.setConversationId(conversationId);
        response.setAiResponse("抱歉，我现在无法完全理解你的问题。请尝试重新描述你想了解的内容，我会尽力帮助你。");
        response.setResponseType(AiGuidanceResponse.ResponseType.CLARIFICATION);
        response.setConfidence(30);
        response.addSuggestedQuestion("能具体说明你想了解的技术动作吗？");
        response.addSuggestedQuestion("你希望改进哪个方面的表现？");
        return response;
    }
    
    /**
     * 获取运动类型显示名称
     */
    private String getSportDisplayName(String sportType) {
        switch (sportType.toLowerCase()) {
            case "running": return "跑步";
            case "basketball_shooting": return "篮球投篮";
            case "tennis_serve": return "网球发球";
            case "golf_swing": return "高尔夫挥杆";
            case "swimming": return "游泳";
            default: return "运动";
        }
    }
} 